package main

import (
	"bytes"
	"fmt"
	"io"
	"net/http"
	"strings"
	"time"
)

// JenkinsConfig Jenkins 配置结构
type JenkinsConfig struct {
	URL      string
	Username string
	Token    string
	Timeout  time.Duration
}

// JenkinsMCPServer Jenkins MCP 服务器
type JenkinsMCPServer struct {
	config JenkinsConfig
	client *http.Client
}

// JobConfig 作业配置结构
type JobConfig struct {
	Name        string                 `json:"name"`
	Description string                 `json:"description"`
	Type        string                 `json:"type"` // "freestyle", "pipeline", "multibranch"
	Config      map[string]interface{} `json:"config"`
	SCM         *SCMConfig             `json:"scm,omitempty"`
	Triggers    []TriggerConfig        `json:"triggers,omitempty"`
	Parameters  []ParameterConfig      `json:"parameters,omitempty"`
}

// SCMConfig 源代码管理配置
type SCMConfig struct {
	Type       string `json:"type"` // "git", "svn"
	URL        string `json:"url"`
	Branch     string `json:"branch"`
	Credential string `json:"credential,omitempty"`
}

// TriggerConfig 触发器配置
type TriggerConfig struct {
	Type   string `json:"type"` // "cron", "scm", "webhook"
	Config string `json:"config"`
}

// ParameterConfig 参数配置
type ParameterConfig struct {
	Name         string   `json:"name"`
	Type         string   `json:"type"` // "string", "boolean", "choice"
	DefaultValue string   `json:"default_value"`
	Description  string   `json:"description"`
	Choices      []string `json:"choices,omitempty"`
}

// BuildInfo 构建信息
type BuildInfo struct {
	Number      int    `json:"number"`
	URL         string `json:"url"`
	Status      string `json:"status"`
	Result      string `json:"result"`
	Duration    int64  `json:"duration"`
	Timestamp   int64  `json:"timestamp"`
	Description string `json:"description"`
}

// JobInfo 作业信息
type JobInfo struct {
	Name        string      `json:"name"`
	URL         string      `json:"url"`
	Description string      `json:"description"`
	Buildable   bool        `json:"buildable"`
	LastBuild   *BuildInfo  `json:"lastBuild"`
	Builds      []BuildInfo `json:"builds"`
}

// NewJenkinsMCPServer 创建新的 Jenkins MCP 服务器
func NewJenkinsMCPServer(config JenkinsConfig) (*JenkinsMCPServer, error) {
	if config.URL == "" {
		return nil, fmt.Errorf("Jenkins URL is required")
	}
	if config.Username == "" {
		return nil, fmt.Errorf("Jenkins username is required")
	}
	if config.Token == "" {
		return nil, fmt.Errorf("Jenkins token is required")
	}
	if config.Timeout == 0 {
		config.Timeout = 30 * time.Second
	}

	client := &http.Client{
		Timeout: config.Timeout,
	}

	server := &JenkinsMCPServer{
		config: config,
		client: client,
	}

	// 测试连接
	if err := server.testConnection(); err != nil {
		return nil, fmt.Errorf("failed to connect to Jenkins: %v", err)
	}

	return server, nil
}

// testConnection 测试与 Jenkins 的连接
func (j *JenkinsMCPServer) testConnection() error {
	req, err := http.NewRequest("GET", j.config.URL+"/api/json", nil)
	if err != nil {
		return err
	}

	req.SetBasicAuth(j.config.Username, j.config.Token)
	req.Header.Set("Content-Type", "application/json")

	resp, err := j.client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("Jenkins connection failed with status: %d", resp.StatusCode)
	}

	return nil
}

// makeRequest 发送 HTTP 请求到 Jenkins
func (j *JenkinsMCPServer) makeRequest(method, endpoint string, body []byte) (*http.Response, error) {
	url := strings.TrimRight(j.config.URL, "/") + endpoint

	var bodyReader io.Reader
	if body != nil {
		bodyReader = bytes.NewReader(body)
	}

	req, err := http.NewRequest(method, url, bodyReader)
	if err != nil {
		return nil, err
	}

	req.SetBasicAuth(j.config.Username, j.config.Token)
	req.Header.Set("Content-Type", "application/json")

	if method == "POST" && body != nil && bytes.Contains(body, []byte("xml")) {
		req.Header.Set("Content-Type", "application/xml")
	}

	return j.client.Do(req)
}
